package ru.jexp.rcp.supply.update;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.operations.ProvisioningJob;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.UpdateOperation;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.PlatformUI;

import ru.jexp.rcp.supply.Activator;

public class JExpClientUpdater
{

	private static final String JUSTUPDATED = "justupdated";
	private final Activator activator;

	public JExpClientUpdater(Activator activator)
	{
		this.activator = activator;
	}

	@SuppressWarnings("restriction")
	public void update()
	{
		final IProvisioningAgent agent = (IProvisioningAgent)
				ServiceHelper.getService(activator.getBundle().getBundleContext(),
					IProvisioningAgent.SERVICE_NAME);
		final IPreferenceStore prefStore =
				Activator.getDefault().getPreferenceStore();
		if (prefStore.getBoolean(JUSTUPDATED))
		{
			prefStore.setValue(JUSTUPDATED, false);
			return;
		}

		IRunnableWithProgress runnable = new IRunnableWithProgress()
		{
			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
			{
				IStatus updateStatus = checkForUpdates(agent, monitor);
				if (updateStatus.getSeverity() != IStatus.ERROR && updateStatus.getCode() != UpdateOperation.STATUS_NOTHING_TO_UPDATE)
				{
					prefStore.setValue(JUSTUPDATED, true);
					PlatformUI.getWorkbench().restart();
				}
			}
		};
		try
		{
			new ProgressMonitorDialog(null).run(true, true, runnable);
		}
		catch (InvocationTargetException e)
		{
			e.printStackTrace();
		}
		catch (InterruptedException e)
		{
		}

	}

	private IStatus checkForUpdates(IProvisioningAgent agent,
			IProgressMonitor monitor) throws OperationCanceledException
	{
		ProvisioningSession session = new ProvisioningSession(agent);
		UpdateOperation operation = new UpdateOperation(session);
		SubMonitor sub = SubMonitor.convert(monitor, "Checking for application updates...", 200);
		IStatus status = operation.resolveModal(sub.newChild(100));
		if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE)
		{
			// MessageDialog.openInformation(null, "", "VSE OK");
			return status;
		}
		if (status.getSeverity() == IStatus.CANCEL)
		{
			throw new OperationCanceledException();
		}

		if (status.getSeverity() != IStatus.ERROR)
		{
			ProvisioningJob job = operation.getProvisioningJob(null);
			status = job.runModal(sub.newChild(100));
			if (status.getSeverity() == IStatus.CANCEL)
			{
				throw new OperationCanceledException();
			}
		}
		return status;
	}
}
